#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using pii = pair<int, int>;
#define rep(i, a, b) for (int i = (a); i <= (b); i++)
#define per(i, a, b) for (int i = (a); i >= (b); i--)
#define endl '\n'
const int N = 5e5 + 5;

int n, m;
struct Node {
  int x, y, z;
  bool operator<(const Node& o) const {
    if (x != o.x)
      return x < o.x;
    else if (y != o.y)
      return y > o.y;  // deal with the condition of x1 == x2,
    else
      return z < o.z;
  }
} a[N], b[N];
int ans;
// very strange use of CDQ with heap, I hope it would wok.
bool vis[N];
void cdq(int& l, int& r) {
  if (l >= r) return;
  int mid = (l + r) >> 1;
  int l1 = l, r1 = mid, l2 = mid + 1, r2 = r;
  cdq(l1, r1), cdq(l2, r2);
  rep(i, l1, r1) vis[i] = 0;
  priority_queue<pii, vector<pii>, greater<pii>> pq;
  int j = l1;
  rep(i, l2, r2) {
    int x = a[i].x, y = a[i].y, z = a[i].z;
    while (j <= r1 && a[j].y < y) {  // y_j < y
      pq.push(pii(a[j].z, j));
      j++;
    }
    while (pq.size() && pq.top().first < z) {  // z_j < z
      int k = pq.top().second;
      vis[k] = 1;
      pq.pop();
      ans++;
    }
  }
  // merge
  int i = l1, k = l;
  j = l2;
  while (i <= r1 && j <= r2) {
    if (a[i].y <= a[j].y) {
      if (!vis[i]) b[k++] = a[i];
      i++;
    } else {
      b[k++] = a[j++];
    }
  }
  while (i <= r1) {
    if (!vis[i]) b[k++] = a[i];
    i++;
  }
  while (j <= r2) {
    b[k++] = a[j++];
  }
  r = k - 1;
  rep(i, l, r) a[i] = b[i];
}
void solve() {
  cin >> n;
  rep(i, 1, n) cin >> a[i].x;
  rep(i, 1, n) cin >> a[i].y;
  rep(i, 1, n) cin >> a[i].z;
  sort(a + 1, a + n + 1);
  int l = 1, r = n;
  cdq(l, r);
  cout << ans;
  return;
}
int main() {
  ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
  int t = 1;
  while (t--) solve();
  return 0;
}